import * as step from '@flow-step/step-toolkit'
import path from 'path';
import * as semver from 'semver'
import process from "process";

const ENV_USE_FOREIGN_CLUSTER: string = 'useForeignCluster'

export function checkVersionValid(inputGOVersion: string): boolean {
    // 检查 inputGOVersion 是否大于等于 1.6，如果不符合则直接抛出异常
    const version = semver.valid(semver.coerce(inputGOVersion))
    return !(version == null || semver.lt(version, '1.6.0'));
}

export async function installGO(inputGOVersion: string, goPath: string): Promise<void> {
    let toolName: string = 'go'
    let goVersion: string = mapGOVersion(inputGOVersion)
    if (!checkVersionValid(goVersion)) {
        throw new Error(`The input version ${inputGOVersion} is not supported, please use version >= 1.6.0`)
    }

    step.info(`Going to install the go with version ${goVersion}`)

    let latestPatchVersion = ""

    try {
        let platform: string = step.platform.getPlatform()
        let toolSuffix = getToolSuffix(platform)

        // get latest matched goVersion
        latestPatchVersion = await step.tool.formatToLatestPatchVersion(toolName, "", goVersion)
        const goCachedPath = await step.tool.install(toolName, latestPatchVersion, toolSuffix)
        setupGO(goCachedPath, goPath)
    } catch (err) {
        throw new Error(`Install GO ${inputGOVersion} failed, ${err}`)
    }

    exportGoEnvs(latestPatchVersion)
    step.info(`Install GO ${goVersion} -> ${latestPatchVersion} successfully!`)
}

export function exportGoEnvs(latestPatchVersion: string): void {
    if (semver.gte(latestPatchVersion, '1.13.0')) {
        step.info("export GO111MODULE=on")
        step.exportEnvVar('GO111MODULE', 'on')
    }

    const useForeignCluster: string | undefined =
        process.env[ENV_USE_FOREIGN_CLUSTER]
    if (useForeignCluster == undefined || useForeignCluster != 'true') {
        step.info("export GOPROXY=https://goproxy.cn")
        step.exportEnvVar('GOPROXY', 'https://goproxy.cn')
    } else {
        step.info("Please DO NOT use domestic repository or proxy when use oversea build cluser!")
    }
}

export function setupGO(goCachedPath: string, goPath: string): void {
    let goRootPath = goCachedPath
    step.info(`GOROOT: ${goRootPath}`)
    step.exportEnvVar('GOROOT', goRootPath)

    let goBinPath = path.join(goRootPath, 'bin')
    step.info(`go bin path: ${goBinPath}`)
    step.addPath(goBinPath)

    step.info(`GOPATH: ${goPath}`)
    step.exportEnvVar('GOPATH', goPath)
}

export function getToolSuffix(platform: string): string {
    return platform === step.platform.PLATFORM_WIN ? "zip" : "tar.gz";
}

// 1.8.x -> 1.8; 1.22.1 -> 1.22.1
export function mapGOVersion(goVersion: string): string {
    const match = goVersion.match(/^(\d+\.\d+)\.x$/);
    if (match) {
        return match[1];
    }

    return goVersion;
}